# @Version        : 1.0
# @Update Time    : 2024/12/11 22:25
# @File           : resource_controller.py
# @IDE            : PyCharm
# @Desc           : 文件描述信息
from fastapi import APIRouter, Depends, Form, UploadFile, File
from fastapi.responses import HTMLResponse
from fastapi_utils.cbv import cbv
from sqlalchemy import and_
from sqlalchemy.ext.asyncio import AsyncSession

from authx.dependencies.permission import PermissionChecker
from src import schemas
from src.core.base_controller import BaseController
from src.core.dependencies import IdList
from src.core.response.response_schema import (
    ResponseGenericSchema,
    ResponseSchema,
    PageResponse,
)
from src.db.db_database import alchemy
from src.models import SysResource
from src.schemas.resource_schema import ResourceParams
from src.services.resource_service import ResourceService
from src.utils.file.base import AbstractUpload
from src.utils.file.file_factory import FileUploadFactory

router = APIRouter()


@cbv(router)
class ResourceController(BaseController):
    db: AsyncSession = Depends(alchemy.provide_session())
    resource_service: ResourceService = Depends(alchemy.provide_service(ResourceService))

    @router.get(
        "/list",
        summary="资源列表",
        response_model=PageResponse[schemas.ResourceOut],
        dependencies=[Depends(PermissionChecker("system:resource:list"))],
    )
    async def get_resource_list(self, param: ResourceParams = Depends()):
        where = await param.get_where_and_limit_offset(SysResource)
        data, count = await self.resource_service.list_and_count(*where)
        return self.paginated_response(
            data=data, total=count, current=param.page, size=param.limit
        )

    # 文件上传
    @router.post(
        "/upload",
        summary="文件上传",
        description="文件上传",
        response_model=ResponseSchema,
        dependencies=[Depends(PermissionChecker("system:resource:upload"))],
    )
    async def upload_file(
        self,
        file: UploadFile = File(...),
        path: str = Form(..., description="文件保存路径"),
        user_id: str = Depends(PermissionChecker("system:resource:upload")),
    ):
        file_info = await FileUploadFactory.get_upload_strategy("local").upload_image(
            path, file, accept=AbstractUpload.ALL_ACCEPT, max_size=10
        )
        # 文件
        file_type = AbstractUpload.upload_type(file)
        # 添加
        await self.resource_service.create(
            {
                "filename": file.filename,
                "url": file_info.get("remote_path"),
                "file_type": file_type.value,
                "create_by": user_id,
            },
            auto_commit=True,
        )
        return self.success(data=file_info.get("remote_path"))

    # 删除资源
    @router.delete(
        "/delete",
        summary="删除资源",
        description="删除资源",
        dependencies=[Depends(PermissionChecker("system:resource:delete"))],
        response_model=ResponseSchema,
    )
    async def delete_resource(self, ids: IdList = Depends()):
        # 查询删除本地数据
        resource_list = await self.resource_service.list(
            and_(SysResource.id.in_(ids.ids))
        )
        for resource in resource_list:
            await FileUploadFactory.get_upload_strategy("local").delete_file(
                resource.url
            )
        await self.resource_service.delete_many(ids.ids, auto_commit=True)
        return self.success(message="删除成功")

    @router.get(
        "/preview",
        summary="数据分析",
        description="数据分析",
        response_class=HTMLResponse,
        dependencies=[Depends(PermissionChecker("system:resource:list"))],
    )
    async def preview_file(self):
        """
        预览文件
        """
        import pygwalker as pyg
        import pandas as pd

        # 创建应该随机df
        df = pd.DataFrame(
            {
                "id": range(100),
                "name": [f"name_{i}" for i in range(100)],
                "age": [i for i in range(100)],
                "height": [i * 1.1 for i in range(100)],
                "weight": [i * 2.2 for i in range(100)],
                "gender": ["male" if i % 2 == 0 else "female" for i in range(100)],
            }
        )
        html_str = pyg.to_html(df)
        return HTMLResponse(content=html_str)
